package com.l2j.test.web.admin.controller.execl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.l2j.test.model.entity.LinkContrSignSerialNum;
import com.l2j.test.web.admin.service.LinkContrSignSerialNumService;
import com.l2j.test.web.admin.vo.excel.SerialNumVo;
import com.l2j.test.web.admin.vo.excel.SerialPropertyVo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
public class SerialExport {

    @Autowired
    private LinkContrSignSerialNumService linkContrSignSerialNumService;

    @GetMapping("/export/serial")
    public ResponseEntity<byte[]> exportToExcel() throws IOException {

        //获取全部产品分类、产品渠道
//        List<LinkContrSignSerialNum> list = linkContrSignSerialNumService.lambdaQuery()
//                .select(LinkContrSignSerialNum::getClassCode, LinkContrSignSerialNum::getProductAttribute)
//                .groupBy(LinkContrSignSerialNum::getClassCode, LinkContrSignSerialNum::getProductAttribute)
//                .list();
//        System.out.print(list);
        //获取签约序号信息
        //模拟输入参数
        String parameter = "ECAF01,EPAAA02-04,EPAAA93,EPAAB01-99,EPAAD20-21,EPAAD30,EPAAD92-93,EPAAE01-99,EPAAH01-99,EPAAI11-14,EPAAI92,EPAAI94,EPAAJ01-99,EZAAA01-99,EZAAB01-99,EZAAD01-99,EZAAE01-99,EZAAI01-99,EZAAJ01-99,EZABA01-99,EZABD01-99,EZABE01-99,EZADF01-99";
        // 正则表达式
        String regex = "([A-Za-z]+)(\\d+)-(\\d+)|([A-Za-z]+)(\\d+)";
        LambdaQueryWrapper<LinkContrSignSerialNum> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(LinkContrSignSerialNum::getSerialNumber, LinkContrSignSerialNum::getProjectAttribute, LinkContrSignSerialNum::getProductAttribute);
        // 创建 Pattern 对象
        Pattern pattern = Pattern.compile(regex);
        // 创建 Matcher 对象
        Matcher matcher = pattern.matcher(parameter);
        // 查找所有匹配项
        while (matcher.find()) {
            // 如果是带范围的条件 (如 A1-3)
            if (matcher.group(1) != null && matcher.group(2) != null && matcher.group(3) != null) {
                String column = matcher.group(1);
                String start = matcher.group(2);
                String end = matcher.group(3);
                wrapper.or().eq(LinkContrSignSerialNum::getSerialNumberPrefix, column).between(LinkContrSignSerialNum::getSerialNumberValue, start, end);
            }
            // 如果是单个值的条件 (如 D10)
            else if (matcher.group(4) != null && matcher.group(5) != null) {
                String value = matcher.group(4) + matcher.group(5);
                wrapper.or().eq(LinkContrSignSerialNum::getSerialNumber, value);
            }
        }
        List<LinkContrSignSerialNum> serialNumList = linkContrSignSerialNumService.list(wrapper);
        //用Set提取”行业属性 - 产品属性“的唯一值
        Set<String> serialPropertySet = new LinkedHashSet<>();
        for (int i = 1 ; i < serialNumList.size() ; i++) {
            serialPropertySet.add(serialNumList.get(i).getProjectAttribute() + "-" + serialNumList.get(i).getProductAttribute());
        }
        //转换回数组获得索引
        String[] serialPropertySetArray = serialPropertySet.toArray(new String[0]);
        List<SerialPropertyVo> serialNumVoList = serialNumList.stream()
                .map(entity -> {
                    SerialPropertyVo vo = new SerialPropertyVo();
                    //BeanUtils.copyProperties(entity, vo);
                    vo.setSerialNumber(entity.getSerialNumber());
                    vo.setSerialProperty(entity.getProjectAttribute() + "-" + entity.getProductAttribute()); ;
                    return vo;
                })
                .toList();
        for (SerialPropertyVo serialPropertyVo : serialNumVoList) {
            serialPropertyVo.setY(Arrays.asList(serialPropertySetArray).indexOf(serialPropertyVo.getSerialProperty()));
        }
        //将同一单元格的签约号累加
        int yMax = serialNumVoList.stream().mapToInt(SerialPropertyVo::getY).max().orElse(0);
        String[] exportData = new String[yMax + 1];
        for(SerialPropertyVo serialPropertyVo : serialNumVoList) {
            int y = serialPropertyVo.getY();
            if(exportData[y] == null) {
                exportData[y] = serialPropertyVo.getSerialNumber();
            }else {
                //exportData[y] = exportData[y] + '\n'+serialPropertyVo.getSerialNumber();
                exportData[y] = exportData[y] + '、'+serialPropertyVo.getSerialNumber();
            }
        }
        //填充数据，Excel是Workbook,返回的是通过Workbook创建的Sheet,填充的对象是通过sheet创建的Row、Cell
        ByteArrayOutputStream wbStream = new ByteArrayOutputStream();
        try(Workbook wb = new XSSFWorkbook()) {
            Sheet sheet1 = wb.createSheet("签约号清单");
            CellStyle cellStyle = wb.createCellStyle();
            cellStyle.setWrapText(true);
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            for(int i = 0 ;i<yMax;i++) {
                Row row = sheet1.createRow(i+1);
                row.createCell(0).setCellValue(serialPropertySetArray[i]);
                row.createCell(2).setCellValue(exportData[i]);
                row.getCell(0).setCellStyle(cellStyle);
                row.getCell(2).setCellStyle(cellStyle);
            }
            //填充表头
            Row rowHead = sheet1.createRow(0);
            rowHead.createCell(0).setCellValue("产品属性");
            rowHead.getCell(0).setCellStyle(cellStyle);
            rowHead.createCell(1).setCellValue("全签/挑签");
            rowHead.getCell(1).setCellStyle(cellStyle);
            rowHead.createCell(2).setCellValue("签约号");
            rowHead.getCell(2).setCellStyle(cellStyle);
            //设置行宽
            sheet1.autoSizeColumn(2,false);
            sheet1.setColumnWidth(2,60000);
            wb.write(wbStream);
        }
        
        // 设置响应头
        HttpHeaders headersResponse = new HttpHeaders();
        //headersResponse.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //headersResponse.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        //headersResponse.setContentDispositionFormData("attachment", "00.xlsx");
        String fileName = URLEncoder.encode("测试文件.xlsx", "UTF-8").replaceAll("\\+", "%20");
        headersResponse.setContentDispositionFormData("attachment", fileName);

        return ResponseEntity.ok()
                .headers(headersResponse)
                //.body(outputStream.toByteArray());
                .body(wbStream.toByteArray());
    }
}

